import type { CustomRequestOptions } from "@/http/types";
import { md5 } from "js-md5";
import { useTokenStore } from "@/store";
import { useUserStore } from "@/store/user";
import { AppId, getEnvBaseUrl } from "@/utils";
import { stringifyQuery } from "./tools/queryString";

// 请求基准地址
const baseUrl = getEnvBaseUrl();
const appId = AppId;

// 获取动态参数
function getDynamicParams(url: string, unionId: string) {
  // 3. 添加 token 请求头标识
  const tokenStore = useTokenStore();
  const token = tokenStore.validToken;
  if (
    url.includes("/api/wx/api/getWxUserInfo") ||
    url.includes("/user-mgr/login")
  ) {
    console.log("currentUrl is to getWxUserInfo");
    return {
      appkey: appId,
      r: Date.now(), // 当前时间戳
      nonce: Math.floor(Math.random() * 1000000), // 随机数
    };
  }
  return {
    appkey: appId,
    r: Date.now(), // 当前时间戳
    nonce: Math.floor(Math.random() * 1000000), // 随机数
    companyId: 1,
    roleName: "root",
    unionId,
    token,
  };
}

// 生成签名（根据你的签名规则实现）
function generateSign(params) {
  // 这里需要根据你的签名算法实现
  // 示例：参数排序后拼接+加密
  const sortedParams = Object.keys(params)
    .sort()
    .map((key) => `${key}=${params[key]}`)
    .join("&");
  return md5(sortedParams);
}

// 拦截器配置
const httpInterceptor = {
  // 拦截前触发
  invoke(options: CustomRequestOptions) {
    // 如果您使用了alova，则请把下面的代码放开注释
    // alova 执行流程：alova beforeRequest --> 本拦截器 --> alova responded
    // return options

    // 非 alova 请求，正常执行
    // 接口请求支持通过 query 参数配置 queryString
    if (options.query) {
      const queryStr = stringifyQuery(options.query);
      if (options.url.includes("?")) {
        options.url += `&${queryStr}`;
      } else {
        options.url += `?${queryStr}`;
      }
    }
    // 非 http 开头需拼接地址
    if (!options.url.startsWith("http")) {
      // #ifdef H5
      if (JSON.parse(import.meta.env.VITE_APP_PROXY_ENABLE)) {
        // 自动拼接代理前缀
        options.url = import.meta.env.VITE_APP_PROXY_PREFIX + options.url;
      } else {
        options.url = baseUrl + options.url;
      }
      // #endif
      // 非H5正常拼接
      // #ifndef H5
      options.url = baseUrl + options.url;
      // #endif
      // TIPS: 如果需要对接多个后端服务，也可以在这里处理，拼接成所需要的地址
    }
    // 1. 请求超时
    options.timeout = 60000; // 60s
    // 2. （可选）添加小程序端请求头标识
    options.header = {
      ...options.header,
    };

    const userStore = useUserStore();
    const unionId = userStore.userInfo.unionId;
    const dynamicParams = getDynamicParams(options.url, unionId);

    const allParams = {
      ...dynamicParams,
      ...options.data,
    };

    // 获取所有参数

    // 生成签名
    allParams.sign = generateSign(allParams);

    // 更新请求数据
    options.data = allParams;
    // 3. 添加 token 请求头标识
    const tokenStore = useTokenStore();
    const token = tokenStore.validToken;
    if (token) {
      options.header.Authorization = `Bearer ${token}`;
    }
    return options;
  },
};

export const requestInterceptor = {
  install() {
    // 拦截 request 请求
    uni.addInterceptor("request", httpInterceptor);
    // 拦截 uploadFile 文件上传
    uni.addInterceptor("uploadFile", httpInterceptor);
  },
};
